﻿using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace 五分钟计时
{
    public class KeyboardHookLib
    {
        //客户端键盘处理事件
        public delegate void ProcessKeyHandle(HookStruct param, out bool handle);

        private const int WH_KEYBOARD_LL = 13; //键盘

        //接收SetWindowsHookEx返回值
        private static int _hHookValue;
        private static ProcessKeyHandle _clientMethod;

        //勾子程序处理事件
        private HookHandle _KeyBoardHookProcedure;
        private IntPtr _hookWindowPtr = IntPtr.Zero;

        //Hook结构

        //设置钩子
        [DllImport("user32.dll")]
        private static extern int SetWindowsHookEx(int idHook, HookHandle lpfn, IntPtr hInstance, int threadId);

        //取消钩子
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern bool UnhookWindowsHookEx(int idHook);

        //调用下一个钩子
        [DllImport("user32.dll")]
        private static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);

        //获取当前线程ID
        [DllImport("kernel32.dll")]
        private static extern int GetCurrentThreadId();

        //Gets the main module for the associated process.
        [DllImport("kernel32.dll")]
        private static extern IntPtr GetModuleHandle(string name);

        /// &lt;summary&gt;
        /// 安装勾子
        /// &lt;/summary&gt;
        /// &lt;param name="hookProcess"&gt;外部调用的键盘处理事件&lt;/param&gt;
        public void InstallHook(ProcessKeyHandle clientMethod)
        {
            _clientMethod = clientMethod;

            // 安装键盘钩子
            if (_hHookValue == 0)
            {
                _KeyBoardHookProcedure = GetHookProc;

                _hookWindowPtr = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);

                _hHookValue = SetWindowsHookEx(
                    WH_KEYBOARD_LL,
                    _KeyBoardHookProcedure,
                    _hookWindowPtr,
                    0);

                //如果设置钩子失败.
                if (_hHookValue == 0)

                    UninstallHook();
            }
        }

        //取消钩子事件
        public void UninstallHook()
        {
            if (_hHookValue != 0)
            {
                bool ret = UnhookWindowsHookEx(_hHookValue);
                if (ret) _hHookValue = 0;
            }
        }

        //钩子事件内部调用,调用_clientMethod方法转发到客户端应用。
        private static int GetHookProc(int nCode, int wParam, IntPtr lParam)
        {
            if (nCode >= 0)
            {
                //转换结构
                var hookStruct = (HookStruct) Marshal.PtrToStructure(lParam, typeof (HookStruct));

                if (_clientMethod != null)
                {
                    bool handle = false;
                    //调用客户提供的事件处理程序。
                    _clientMethod(hookStruct, out handle);
                    if (handle) return 1; //1:表示拦截键盘,return 退出
                }
            }
            return CallNextHookEx(_hHookValue, nCode, wParam, lParam);
        }

        private delegate int HookHandle(int nCode, int wParam, IntPtr lParam);

        [StructLayout(LayoutKind.Sequential)]
        public class HookStruct
        {
            public int vkCode;
            public int scanCode;
            public int flags;
            public int time;
            public int dwExtraInfo;
        }
    }
}

//Form class 加入 private KeyboardHookLib _keyboardHook;
//Form load 方法加入{ 
//  _keyboardHook = new KeyboardHookLib();
//  _keyboardHook.InstallHook(KeyPress);
//    }
//Form closed 方法加入{
// if (_keyboardHook != null) _keyboardHook.UninstallHook();
//}

//插入方法
//public void KeyPress(KeyboardHookLib.HookStruct hookStruct, out bool handle)
        //{
            //handle = false; //预设不拦截任何键

            //            if (hookStruct.vkCode == 91) // 截获左win(开始菜单键)
            //            {
            //                handle = true;
            //            }

            //            if (hookStruct.vkCode == 92) // 截获右win
            //            {
            //                handle = true;
            //            }

            ////截获Ctrl+Esc
            //            if (hookStruct.vkCode == (int) Keys.Escape && (int) ModifierKeys == (int) Keys.Control)
            //            {
            //                handle = true;
            //            }

            ////截获alt+f4
            //            if (hookStruct.vkCode == (int) Keys.F4 && (int) ModifierKeys == (int) Keys.Alt)
            //            {
            //                handle = true;
            //            }

            ////截获alt+tab
            //            if (hookStruct.vkCode == (int) Keys.Tab && (int) ModifierKeys == (int) Keys.Alt)
            //            {
            //                handle = true;
            //            }

            ////截获F1
            //            if (hookStruct.vkCode == (int) Keys.F1)
            //            {
            //                handle = true;
            //            }

            ////截获Ctrl+Alt+Delete
            //            if ((int) ModifierKeys == (int) Keys.Control + (int) Keys.Alt + (int) Keys.Delete)
            //            {
            //                handle = true;
            //            }

            ////如果键A~Z
            //            if (hookStruct.vkCode >= (int) Keys.A && hookStruct.vkCode <= (int) Keys.Z)
            //            {
            ////挡掉G键，想要挡掉哪些键就把下面的G换成那个要挡掉的键，同理可以挡多个
            //                if (hookStruct.vkCode == (int) Keys.G)
            //                    hookStruct.vkCode = (int) Keys.None; //设键为0

            //               // handle = true;
            //            }
            //    if (hookStruct.vkCode == (int)Keys.Q)
            //    {
            //        SendKeys.Send("w");

            //    }





            //    var key = (Keys)hookStruct.vkCode;
            //    label1.Text = "你按下:" + (key == Keys.None ? "" : key.ToString());
            //} 